package org.tio.sitexxx.web.server.controller.base;

import java.awt.image.BufferedImage;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.core.Node;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.UploadFile;
import org.tio.http.server.annotation.RequestPath;
import org.tio.sitexxx.im.server.Ims;
import org.tio.sitexxx.im.server.handler.GroupChatReqHandler;
import org.tio.sitexxx.im.server.handler.P2PChatReqHandler;
import org.tio.sitexxx.service.model.main.ChatRecord;
import org.tio.sitexxx.service.model.main.Img;
import org.tio.sitexxx.service.model.main.User;
import org.tio.sitexxx.service.model.main.Video;
import org.tio.sitexxx.service.service.ImServerService;
import org.tio.sitexxx.service.service.ImgService;
import org.tio.sitexxx.service.service.VideoService;
import org.tio.sitexxx.service.service.base.UserRoleService;
import org.tio.sitexxx.service.service.base.UserService;
import org.tio.sitexxx.service.service.conf.ConfService;
import org.tio.sitexxx.service.vo.AppCode;
import org.tio.sitexxx.service.vo.Const;
import org.tio.sitexxx.service.vo.SimpleUser;
import org.tio.sitexxx.web.server.utils.ImgUtils;
import org.tio.sitexxx.web.server.utils.UploadUtils;
import org.tio.sitexxx.web.server.utils.VideoUtils;
import org.tio.sitexxx.web.server.utils.WebUtils;
import org.tio.utils.hutool.StrUtil;
import org.tio.utils.json.Json;
import org.tio.utils.resp.Resp;

import com.jfinal.kit.Ret;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ImageUtil;

/**
 * 
 * @author tanyaowu
 */
@RequestPath(value = "/im")
public class ImController {
	private static Logger log = LoggerFactory.getLogger(ImController.class);

	public static final String SUBDIR_VIDEO = org.tio.sitexxx.service.vo.Const.UPLOAD_DIR.IM_VIDEO;

	public static final String SUBDIR_IMG = org.tio.sitexxx.service.vo.Const.UPLOAD_DIR.IM_IMG;

	/**
	 * 获取im服务器地址
	 * @param request
	 * @param groupid
	 * @return
	 * @throws Exception
	 */
	@RequestPath(value = "/imserver")
	public Resp imserver(HttpRequest request, String groupid) throws Exception {

		System.out.println("call and return the url for wss connection ");
		//		User currUer = WebUtils.currUser(request);
		Ret ret = ImServerService.me.imserver(groupid);

		if (ret.isOk()) {
			return Resp.ok().data(new Node(ret.getStr("ip"), WebUtils.getImServerPort(request)));
		} else {
			return Resp.fail(ret.getStr("msg"));
		}
	}

	/**
	 * 用户上传的视频
	 * @param request
	 * @param uploadFile
	 * @param group
	 * @return
	 * @author tanyaowu
	 * @throws Exception 
	 */
	private Resp processUploadedVideo(HttpRequest request, UploadFile uploadFile, String group) throws Exception {
		User curr = WebUtils.currUser(request);

		byte[] bs = uploadFile.getData();
		String filename = uploadFile.getName();
		//		filename = URLDecoder.decode(filename, "utf-8");
		String extName = FileUtil.extName(filename);

		Resp ret = null;
		if (UserService.isSupper(curr) || UserRoleService.hasRole(curr, Const.Role.UPLOAD_VIDEO)) {

		} else {
			int starttime = ConfService.getInt("im.upload.video.starttime", 9);
			int endtime = ConfService.getInt("im.upload.video.endtime", 10);
			int maxsize = ConfService.getInt("im.upload.video.maxsize", 1024 * 10);

			int hour = DateUtil.hour(new Date(), true);

			if (hour < starttime || hour >= endtime) {
				ret = Resp.fail("视频上传开放时间[" + starttime + ":00 - " + endtime + ":00]");
			} else if (bs.length > 1024 * maxsize) {
				ret = Resp.fail("文件尺寸不能大于" + maxsize + "KB");
			}
		}
		//		org.tio.sitexxx.web.server.utils.UploadUtils.newFile("im-upload-data", curr.getId())

		if (curr == null) {
			ret = Resp.fail("您尚未登录或登录超时").code(AppCode.ForbidOper.NOTLOGIN);
		}

		Integer uid = null;
		if (curr != null) {
			uid = curr.getId();
		} else {
			uid = 1;
		}

		String videoUrlWithoutExt = UploadUtils.newFile(SUBDIR_VIDEO, uid, filename);
		String videoUrl = videoUrlWithoutExt + "." + extName;

		String videoFilePath = Const.RES_ROOT + videoUrl;
		FileUtil.writeBytes(bs, videoFilePath);

		String coverExt = "jpg";
		String coverUrl = UploadUtils.newFile(SUBDIR_VIDEO, uid, FileUtil.mainName(filename)) + "." + coverExt;
		String coverFilePath = Const.RES_ROOT + coverUrl;

		//		String filename = FileUtil.getName(videoFilePath);
		Video video = VideoUtils.processVideo(videoFilePath, coverFilePath, 400, coverExt);
		video.setUrl(videoUrl);
		video.setUid(uid);

		video.setComefrom(Video.ComeFrom.IM_UPLOAD);
		video.setCoverurl(coverUrl);
		video.setStatus((byte) 1);
		video.setTitle(filename);
		video.setFilename(filename);
		video.setSession(request.getHttpSession().getId());

		boolean f = VideoService.me.save(video);

		//不管成功与否都保存视频
		if (ret != null) {
			return ret;
		}

		if (f) {
			return Resp.ok(video);
		} else {
			return Resp.fail().data(video);
		}

	}

	/**
	 * groupid和touid只能有一个有值，groupid有值时，表示是群聊，touid有值时，表示是私聊
	 * @param request
	 * @param uploadFile
	 * @param groupid
	 * @param touid
	 * @param cid
	 * @return
	 * @throws Exception
	 * @author tanyaowu
	 */
	@RequestPath(value = "/uploadvideo")
	public Resp uploadvideo(HttpRequest request, UploadFile uploadFile, String groupid, Integer touid, String cid) throws Exception {
		try {
			Resp resp = processUploadedVideo(request, uploadFile, groupid);
			if (!resp.isOk()) {
				return resp;
			}

			Video video = (Video) resp.getData();

			String initcontent = video.getId() + "";
			String content = Json.toJson(new Video[] { video });//video.getId() + "";

			return sendVideo(request, initcontent, content, groupid, touid, cid);
		} catch (Exception e) {
			log.error(e.toString(), e);
			return Resp.fail("服务器异常");
		}
	}

	/**
	 * 
	 * @param request
	 * @param initcontent
	 * @param content
	 * @param groupid
	 * @param touid
	 * @param cid
	 * @return
	 * @author tanyaowu
	 */
	private static Resp sendVideo(HttpRequest request, String initcontent, String content, String groupid, Integer touid, String cid) {
		User curr = WebUtils.currUser(request);
		SimpleUser fromUser = SimpleUser.fromUser(curr);
		//群聊
		if (StrUtil.isNotBlank(groupid)) {
			GroupChatReqHandler.groupChatAndLog(request.getHttpSession().getId(), initcontent, content, fromUser,
			        request.getClientIp(), groupid, cid, ChatRecord.ContentType.CARD_VIDEO);
		} else { // 私聊
			ChannelContext channelContext = Ims.getByCid(cid);
			if (channelContext == null) {
				return Resp.fail("发送失败");
			}
			User toUser = UserService.ME.getById(touid);
			SimpleUser to = SimpleUser.fromUser(toUser);
			P2PChatReqHandler.p2pChatAndLog(channelContext, content, content, fromUser, to, ChatRecord.ContentType.CARD_VIDEO);
		}

		return Resp.ok();
	}

	/**
	 * 
	 * @param request
	 * @param uploadFile
	 * @return
	 * @throws Exception 
	 */
	private Resp processUploadedImg(HttpRequest request, UploadFile uploadFile) throws Exception {
		User curr = WebUtils.currUser(request);
		byte[] imageBytes = uploadFile.getData();
		String filename = uploadFile.getName();
		//		filename = URLDecoder.decode(filename, "utf-8");
		String extName = FileUtil.extName(filename);

		Resp ret = null;
		if (UserService.isSupper(curr) || UserRoleService.hasRole(curr, Const.Role.UPLOAD_VIDEO)) {

		} else {
			int starttime = ConfService.getInt("im.upload.img.starttime", 9);
			int endtime = ConfService.getInt("im.upload.img.endtime", 22);
			int maxsize = ConfService.getInt("im.upload.img.maxsize", 2048);

			int hour = DateUtil.hour(new Date(), true);

			if (hour < starttime || hour >= endtime) {
				ret = Resp.fail("图片上传开放时间[" + starttime + ":00 - " + endtime + ":00]");
			}

			if (imageBytes.length > 1024 * maxsize) {
				ret = Resp.fail("文件尺寸不能大于" + maxsize + "KB");
			}
		}

		if (curr == null) {
			ret = Resp.fail("您尚未登录或登录超时").code(AppCode.ForbidOper.NOTLOGIN);
		}

		Integer uid = null;
		if (curr != null) {
			uid = curr.getId();
		} else {
			uid = 1;
		}

		String imgUrlWithoutExt = UploadUtils.newFile(SUBDIR_IMG, uid, filename); //不带后缀的文件路径
		String imgUrl = imgUrlWithoutExt + "." + extName;

		String smImgUrl = imgUrlWithoutExt + "_sm." + extName;

		String imgFilePath = Const.RES_ROOT + imgUrl; //文件路径
		FileUtil.writeBytes(imageBytes, imgFilePath);

		String smImgFilePath = Const.RES_ROOT + smImgUrl;

		BufferedImage bi = ImageUtil.toImage(imageBytes);
		float scale = ImgUtils.calcScaleWithWidth(400, bi);

		Img img = ImgUtils.processImg(bi, imgFilePath, smImgFilePath, scale);
		img.setComefrom(Img.ComeFrom.IM_UPLOAD);
		img.setUid(uid);
		img.setCoverurl(smImgUrl);
		img.setUrl(imgUrl);
		img.setStatus((byte) 1);
		img.setSession(request.getHttpSession().getId());

		boolean f = ImgService.me.save(img);

		if (ret != null) {
			return ret;
		}

		if (f) {
			return Resp.ok(img);
		} else {
			return Resp.fail("服务器异常");
		}

	}

	/**
	 * groupid和touid只能有一个有值，groupid有值时，表示是群聊，touid有值时，表示是私聊
	 * @param request
	 * @param uploadFile
	 * @param groupid
	 * @param touid
	 * @return
	 * @throws Exception
	 * @author tanyaowu
	 */
	@RequestPath(value = "/uploadimg")
	public Resp uploadimg(HttpRequest request, UploadFile uploadFile, String groupid, Integer touid, String cid) throws Exception {
		try {
			Resp resp = processUploadedImg(request, uploadFile);
			if (!resp.isOk()) {
				return resp;
			}

			Img img = (Img) resp.getData();

			String content = Json.toJson(new Img[] { img });

			return sendImg(request, content, groupid, touid, cid);

		} catch (Exception e) {
			log.error(e.toString(), e);
			return Resp.fail("服务器异常");
		}
	}

	/**
	 * groupid和touid只能有一个有值，groupid有值时，表示是群聊，touid有值时，表示是私聊
	 * 上传多张图片
	 * @param request
	 * @param uploadFiles
	 * @param groupid
	 * @param touid
	 * @param cid 通道id
	 * @return
	 * @throws Exception
	 * @author tanyaowu
	 */
	@RequestPath(value = "/uploadimgs")
	public Resp uploadimgs(HttpRequest request, UploadFile[] uploadFiles, String groupid, Integer touid, String cid) throws Exception {
		Img[] imgs = new Img[uploadFiles.length];
		int i = 0;
		for (UploadFile uploadFile : uploadFiles) {
			Resp resp = processUploadedImg(request, uploadFile);
			if (!resp.isOk()) {
				return resp;
			}

			Img img = (Img) resp.getData();
			imgs[i++] = img;

		}

		String content = Json.toJson(imgs);
		return sendImg(request, content, groupid, touid, cid);

	}

	private static Resp sendImg(HttpRequest request, String content, String groupid, Integer touid, String cid) {
		User curr = WebUtils.currUser(request);
		SimpleUser fromUser = SimpleUser.fromUser(curr);
		//群聊
		if (StrUtil.isNotBlank(groupid)) {
			GroupChatReqHandler.groupChatAndLog(request.getHttpSession().getId(), content, content, fromUser, request.getClientIp(),
			        groupid, cid, ChatRecord.ContentType.CARD_IMG);
		} else { // 私聊
			ChannelContext channelContext = Ims.getByCid(cid);
			if (channelContext == null) {
				return Resp.fail("发送失败");
			}
			User toUser = UserService.ME.getById(touid);
			SimpleUser to = SimpleUser.fromUser(toUser);
			P2PChatReqHandler.p2pChatAndLog(channelContext, content, content, fromUser, to, ChatRecord.ContentType.CARD_IMG);
		}

		return Resp.ok();
	}

	//	/**
	//	 * 计算缩放比
	//	 * @param bs
	//	 * @param bi
	//	 * @return
	//	 */
	//	private static double calcScale(byte[] bs, BufferedImage bi) {
	//		int size = bs.length;
	//		int base = 35 * 1024;
	//
	//		if (size <= base) {
	//			return 0.9;
	//		}
	//		double xx = (double) base / (double) size;
	//
	//		return xx;
	//	}
}
